/*
 * Copyright (C) 2008 Alessandro Sivieri <alessandro.sivieri@chimera-bellerofonte.eu>.
 *
 *  This file is part of Daex.
 *
 *  Daex is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Foobar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */
package eu.chimera_bellerofonte.tesi.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PrinterException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.TableModel;

import eu.chimera_bellerofonte.tesi.MainManager;
import eu.chimera_bellerofonte.tesi.DaexIcon;
import eu.chimera_bellerofonte.tesi.DaexLogger;
import eu.chimera_bellerofonte.tesi.DaexProperties;
import eu.chimera_bellerofonte.tesi.datatypes.AlbumWriterException;
import eu.chimera_bellerofonte.tesi.datatypes.DvdException;
import eu.chimera_bellerofonte.tesi.datatypes.DvdNative;
import eu.chimera_bellerofonte.tesi.datatypes.Song;
import eu.chimera_bellerofonte.tesi.encoding.EncoderExecutor;
import eu.chimera_bellerofonte.tesi.ui.models.DaexSongTransferHandler;
import eu.chimera_bellerofonte.tesi.ui.models.DaexTable;
import eu.chimera_bellerofonte.tesi.ui.models.SortedListModel;


/**
 * <p>Questa classe rappresenta il design completo dell'interfaccia
 * grafica del frame principale del programma.</p>
 * <p>Implementa inoltre un renderer utilizzato nelle liste laterali
 * ed un listener per attivare e disattivare le azioni di salvataggio
 * fino ad un nuovo cambiamento.</p>
 * <p>Non esiste una richiesta di salvataggio in caso di chiusura del
 * programma poiche' la possibilita' di salvare le informazioni
 * inserite e' accessoria e non obbligatoria.</p>
 * 
 * @author Sivieri Alessandro
 * @author Vitucci Nicola
 * @version 09/mag/07
 */
public class MainFrame extends JFrame implements ListCellRenderer, PropertyChangeListener
{

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JLabel statusBar = null;
	private JMenuBar jJMenuBar = null;
	private JToolBar jJToolBar = null;
	private JButton openDiscButton = null;
	private JButton openFileButton = null;
	private JButton saveFileButton = null;
	private JButton clearTextButton = null;
	private JButton clearTablesButton = null;
	private JButton encodeButton = null;
	private JTabbedPane jTabbedPane = null;
	private JMenu fileMenu = null;
	private JMenuItem openDiscItem = null;
	private JMenuItem openFileItem = null;
	private JMenuItem saveFileItem = null;
	private JMenuItem saveFileAsItem = null;
	private JMenuItem encodeItem = null;
	private JMenuItem exitItem = null;
	private JMenu editMenu = null;
	private JMenuItem clearTextItem = null;
	private JMenuItem clearTablesItem = null;
	private JMenu viewMenu = null;
	private JMenu aboutMenu = null;
	private JMenuItem showAboutItem = null;
	private JPanel tablesPaneTab = null;
	private JPanel progressPaneTab = null;
	private JPanel generalInfoPane = null;
	private JSplitPane tablesSplit = null;
	private JLabel jLabel = null;
	private JTextField artistTextField = null;
	private JLabel jLabel1 = null;
	private JTextField albumTextField = null;
	private JLabel jLabel2 = null;
	private JComboBox genreComboBox = null;
	private JLabel jLabel3 = null;
	private JSpinner dvdSpin = null;
	private JButton refreshTitleButton = null;
	private JScrollPane leftTableScroll = null;
	private JScrollPane processTableScroll = null;
	private JTable encodingProgressTable = null;
	private JPanel encodingOptionsPane = null;
	private JButton showConsoleButton = null;
	private JProgressBar progressBar = null;
	private JButton abortButton = null;
	private JPanel rightPane = null;
	private JButton printTracksTableButton = null;
	private JMenuItem printTracksTableItem = null;
	private JLabel jLabel4 = null;
	private JTextField deviceTextField = null;
	private JButton changeDeviceButton = null;
	private JPanel[] encodingPanels=new JPanel[3];
	private JPanel[] encodingLowerPanels=new JPanel[3];
	private JButton[] listButtons=new JButton[9];
	private JList[] encodingLists=new JList[3];
	private ListCellRenderer renderer=new DefaultListCellRenderer();
	private JMenu encodeMenu;
	// gruppo di oggetti dal costruttore
	private JTable dvdTable=null;
	private TableModel progressModel=null;
	private SortedListModel[] encodingModels=null;
	private ComboBoxModel genreModel=null;
	private String artist=null;
	private String album=null;
	private SpinnerModel spinModel=null;
	private String device=null;
	// status
	private boolean saveas=false;
	private String filename=null;
	// listener per selezionare il testo
	private FocusAdapter focusAdapter=new FocusAdapter()
	{

		/**
		 * @see java.awt.event.FocusAdapter#focusGained(java.awt.event.FocusEvent)
		 */
		@Override
		public void focusGained(FocusEvent e)
		{
			if(e.getComponent() instanceof JTextField)
			{
				((JTextField) e.getComponent()).selectAll();
			}
		}

		/**
		 * @see java.awt.event.FocusAdapter#focusLost(java.awt.event.FocusEvent)
		 */
		@Override
		public void focusLost(FocusEvent e)
		{
			if(e.getComponent() instanceof JTextField)
			{
				((JTextField) e.getComponent()).select(0, 0);
			}
		}
		
	};
	
	/**
	 * Enum dichiarativo dei parametri da utilizzare nella gestione
	 * enable/disable del frame principale.
	 * 
	 * @see eu.chimera_bellerofonte.tesi.ui.MainFrame#permitActions(ActionParams, boolean)
	 * @author Sivieri Alessandro
	 * @author Vitucci Nicola
	 * @version 31/mag/07
	 */
	public static enum ActionParams
	{
		/**
		 * Apertura di dvd e files.
		 */
		OPEN,
		/**
		 * Salvataggio dello stato su file.
		 */
		SAVE,
		/**
		 * Stampa della tabella principale.
		 */
		PRINT,
		/**
		 * Possibilita' di iniziare l'encoding.
		 */
		ENCODE,
		/**
		 * Editing delle informazioni di disco e traccia.
		 */
		EDITING,
		/**
		 * Funzioni associate durante l'encoding.
		 */
		ENCODING,
		/**
		 * Il solo pulsante "Salva".
		 */
		SAVEONLY,
		/**
		 * La sola azione di abort.
		 */
		ABORT,
		/**
		 * Le azioni "save", "print", "encode", "editing".
		 */
		FULL
	}
	
	/**
	 * <p>Metodo per ottenere l'abilitazione o la disabilitazione
	 * di alcune funzioni di interfaccia a fronte di eventi
	 * precisi.</p>
	 * <p>Il parametro action che indica il tipo di azione
	 * viene preso dall'enumerato ActionParams.
	 * </p>
	 * 
	 * @see eu.chimera_bellerofonte.tesi.ui.MainFrame.ActionParams
	 * @param action il parametro da associare all'azione
	 * @param enable abilitare o meno la funzione passata
	 */
	public void permitActions(ActionParams action, boolean enable)
	{
		if(ActionParams.OPEN.equals( action ))
		{
			openDiscButton.setEnabled(enable);
			openDiscItem.setEnabled(enable);
			openFileButton.setEnabled(enable);
			openFileItem.setEnabled(enable);
		}
		else if(ActionParams.SAVE.equals( action ))
		{
			saveFileAsItem.setEnabled(enable);
			saveFileButton.setEnabled(enable);
			saveFileItem.setEnabled(enable);
		}
		else if(ActionParams.PRINT.equals( action ))
		{
			printTracksTableButton.setEnabled(enable);
			printTracksTableItem.setEnabled(enable);
		}
		else if(ActionParams.ENCODE.equals( action ))
		{
			encodeButton.setEnabled(enable);
			encodeItem.setEnabled(enable);
		}
		else if(ActionParams.EDITING.equals( action ))
		{
			dvdTable.setEnabled(enable);
			for(JList jl: encodingLists)
				jl.setEnabled(enable);
			artistTextField.setEnabled(enable);
			albumTextField.setEnabled(enable);
			genreComboBox.setEnabled(enable);
			clearTextButton.setEnabled(enable);
			clearTextItem.setEnabled(enable);
			for(JButton b: listButtons)
				b.setEnabled(enable);
			clearTablesButton.setEnabled(enable);
			clearTablesItem.setEnabled(enable);
		}
		else if(ActionParams.ENCODING.equals( action ))
		{
			showConsoleButton.setEnabled(enable);
			abortButton.setEnabled(enable);
		}
		else if(ActionParams.FULL.equals( action ))
		{
			permitActions(ActionParams.SAVE, enable);
			permitActions(ActionParams.PRINT, enable);
			permitActions(ActionParams.ENCODE, enable);
			permitActions(ActionParams.EDITING, enable);
			((DaexTable) dvdTable).setInvalidate(!enable);
		}
		else if(ActionParams.SAVEONLY.equals( action ))
		{
			saveFileButton.setEnabled(enable);
			saveFileItem.setEnabled(enable);
		}
		else if(ActionParams.ABORT.equals( action ))
		{
			abortButton.setEnabled(enable);
		}
		else
		{
			DaexLogger.getDaexLogger().warning("Tentativo di abilitare/disabilitare azioni non previste: "+action);
		}
	}

	/**
	 * This method initializes jJMenuBar	
	 * 	
	 * @return javax.swing.JMenuBar	
	 */
	private JMenuBar getJJMenuBar()
	{
		if (jJMenuBar == null)
		{
			jJMenuBar = new JMenuBar();
			jJMenuBar.add(getFileMenu());
			jJMenuBar.add(getEditMenu());
			jJMenuBar.add(getViewMenu());
			jJMenuBar.add(getAboutMenu());
		}
		return jJMenuBar;
	}

	/**
	 * This method initializes jJToolBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private JToolBar getJJToolBar()
	{
		if (jJToolBar == null)
		{
			jJToolBar = new JToolBar();
			jJToolBar.setFloatable(false);
			jJToolBar.add(getOpenDiscButton());
			jJToolBar.add(getOpenFileButton());
			jJToolBar.add(getSaveFileButton());
			jJToolBar.add(getPrintTracksTableButton());
			jJToolBar.add(new JToolBar.Separator());
			jJToolBar.add(getClearTextButton());
			jJToolBar.add(getClearTablesButton());
			jJToolBar.add(new JToolBar.Separator());
			jJToolBar.add(getEncodeButton());
		}
		return jJToolBar;
	}

	/**
	 * This method initializes openDiscButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getOpenDiscButton()
	{
		if (openDiscButton == null)
		{
			openDiscButton = new JButton();
			openDiscButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.OPENDVD)));
			openDiscButton.setToolTipText("Apre un DVD e ne mostra i risultati dell'analisi");
			openDiscButton.setMnemonic(KeyEvent.VK_D);
			openDiscButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Apertura disco...");
					try
					{
						MainManager.getMainManager().setAlbum(getDeviceTextField().getText());
						permitActions(ActionParams.FULL, true);
						permitActions(ActionParams.ENCODING, false);
					}
					catch (DvdException e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Impossibile caricare il dvd, controllarne la presenza", "Errore di caricamento del dvd", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
						permitActions(ActionParams.FULL, false);
						permitActions(ActionParams.ENCODING, false);
					}
					statusBar.setText("Pronto");
				}
			});
		}
		return openDiscButton;
	}

	/**
	 * This method initializes openFileButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getOpenFileButton()
	{
		if (openFileButton == null)
		{
			openFileButton = new JButton();
			openFileButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.OPENFILE)));
			openFileButton.setToolTipText("Apre un file precedentemente salvato");
			openFileButton.setMnemonic(KeyEvent.VK_O);
			openFileButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Apertura file...");
					String[] filters={DaexProperties.getProperty("extension")};
					String[] result=FileChooserUtility.loadFile(MainFrame.this, DaexProperties.getProperty("lastopendir"), "Caricamento file", filters, true);
					if(result!=null && result.length==1)
					{
						File f=new File(result[0]);
						DaexProperties.addProperty("lastopendir", f.getParent());
						try
						{
							MainManager.getMainManager().setAlbum(f, getDeviceTextField().getText());
							permitActions(ActionParams.FULL, true);
							permitActions(ActionParams.ENCODING, false);
						}
						catch (DvdException e1)
						{
							JOptionPane.showMessageDialog(MainFrame.this, "Impossibile caricare il file specificato!", "Errore nel caricamento", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
						}
					}
					statusBar.setText("Pronto");
				}
			});
		}
		return openFileButton;
	}

	/**
	 * This method initializes saveFileButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getSaveFileButton()
	{
		if (saveFileButton == null)
		{
			saveFileButton = new JButton();
			saveFileButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.SAVEFILE)));
			saveFileButton.setToolTipText("Salva lo stato corrente");
			saveFileButton.setMnemonic(KeyEvent.VK_S);
			saveFileButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Salvataggio su file...");
					try
					{
						if(saveas==false)
						{
							String result=FileChooserUtility.saveFile(MainFrame.this, DaexProperties.getProperty("lastopendir"), "untitled"+DaexProperties.getProperty("extension"), "Salvataggio file", DaexProperties.getProperty("extension"));
							if(result!=null)
							{
								File f=new File(result);
								DaexProperties.addProperty("lastopendir", f.getParent());
								MainManager.getMainManager().save(f.getAbsolutePath());
								saveas=true;
								filename=f.getAbsolutePath();
							}
						}
						else
						{
							MainManager.getMainManager().save(filename);
						}
						permitActions(ActionParams.SAVEONLY, false);
					}
					catch (AlbumWriterException e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Impossibile salvare il file specificato!", "Errore nel salvataggio", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
					}
					statusBar.setText("Pronto");
				}
			});
		}
		return saveFileButton;
	}

	/**
	 * This method initializes clearTextButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getClearTextButton()
	{
		if (clearTextButton == null)
		{
			clearTextButton = new JButton();
			clearTextButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.EDITNEW)));
			clearTextButton.setMnemonic(KeyEvent.VK_I);
			clearTextButton.setToolTipText("Riporta le informazioni di traccia allo stato iniziale");
			clearTextButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					MainManager.getMainManager().reinit();
				}
			});
		}
		return clearTextButton;
	}

	/**
	 * This method initializes clearTablesButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getClearTablesButton()
	{
		if (clearTablesButton == null)
		{
			clearTablesButton = new JButton();
			clearTablesButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.CLEARLIST)));
			clearTablesButton.setMnemonic(KeyEvent.VK_T);
			clearTablesButton.setToolTipText("Pulisce tutte le tabelle degli encoders");
			clearTablesButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					MainManager.getMainManager().clearAll();
				}
			});
		}
		return clearTablesButton;
	}

	/**
	 * This method initializes encodeButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getEncodeButton()
	{
		if (encodeButton == null)
		{
			encodeButton = new JButton();
			encodeButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.START)));
			encodeButton.setMnemonic(KeyEvent.VK_C);
			encodeButton.setToolTipText("Inizia le operazioni di encoding delle tracce come specificato");
			encodeButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Encoding...");
					getJTabbedPane().setSelectedIndex(1);
					permitActions(ActionParams.OPEN, false);
					permitActions(ActionParams.FULL, false);
					permitActions(ActionParams.ENCODING, true);
					try
					{
						boolean ret=MainManager.getMainManager().startEncode();
						if(!ret)
						{
							permitActions(ActionParams.OPEN, true);
							permitActions(ActionParams.FULL, true);
							permitActions(ActionParams.ENCODING, false);
						}
					}
					catch (Exception e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Gravi errori di esecuzione, verificare il log!", "Impossibile eseguire la codifica", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
					}
				}
			});
		}
		return encodeButton;
	}

	/**
	 * This method initializes jTabbedPane	
	 * 	
	 * @return javax.swing.JTabbedPane	
	 */
	private JTabbedPane getJTabbedPane()
	{
		if (jTabbedPane == null)
		{
			jTabbedPane = new JTabbedPane();
			jTabbedPane.addTab("Tracce", null, getTablesPaneTab(), "Visualizza la tabella delle tracce del DVD");
			jTabbedPane.addTab("Codifica", null, getProgressPaneTab(), "Visualizza le informazioni di codifica");
		}
		return jTabbedPane;
	}

	/**
	 * This method initializes fileMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getFileMenu()
	{
		if (fileMenu == null)
		{
			fileMenu = new JMenu();
			fileMenu.setText("File");
			fileMenu.setMnemonic(KeyEvent.VK_F);
			fileMenu.add(getOpenDiscItem());
			fileMenu.add(getOpenFileItem());
			fileMenu.add(getSaveFileItem());
			fileMenu.add(getSaveFileAsItem());
			fileMenu.add(getPrintTracksTableItem());
			fileMenu.add(new JSeparator());
			fileMenu.add(getEncodeItem());
			fileMenu.add(getEncodeMenu());
			fileMenu.add(new JSeparator());
			fileMenu.add(getExitItem());
		}
		return fileMenu;
	}

	/**
	 * This method initializes openDiscItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getOpenDiscItem()
	{
		if (openDiscItem == null)
		{
			openDiscItem = new JMenuItem();
			openDiscItem.setText("Apri disco");
			openDiscItem.setMnemonic(KeyEvent.VK_D);
			openDiscItem.setToolTipText("Apre un nuovo DVD e ne visualizza i risultati dell'analisi");
			openDiscItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Apertura disco...");
					try
					{
						MainManager.getMainManager().setAlbum(getDeviceTextField().getText());
						permitActions(ActionParams.FULL, true);
						permitActions(ActionParams.ENCODING, false);
					}
					catch (DvdException e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Impossibile caricare il dvd, controllarne la presenza", "Errore di caricamento del dvd", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
						permitActions(ActionParams.FULL, false);
						permitActions(ActionParams.ENCODING, false);
					}
					statusBar.setText("Pronto");
				}
			});
		}
		return openDiscItem;
	}

	/**
	 * This method initializes openFileItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getOpenFileItem()
	{
		if (openFileItem == null)
		{
			openFileItem = new JMenuItem();
			openFileItem.setText("Apri file");
			openFileItem.setMnemonic(KeyEvent.VK_A);
			openFileItem.setToolTipText("Apre un file precedentemente salvato");
			openFileItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Apertura file...");
					String[] filters={DaexProperties.getProperty("extension")};
					String[] result=FileChooserUtility.loadFile(MainFrame.this, DaexProperties.getProperty("lastopendir"), "Caricamento file", filters, true);
					if(result!=null && result.length==1)
					{
						File f=new File(result[0]);
						DaexProperties.addProperty("lastopendir", f.getParent());
						try
						{
							MainManager.getMainManager().setAlbum(f, getDeviceTextField().getText());
							permitActions(ActionParams.FULL, true);
							permitActions(ActionParams.ENCODING, false);
						}
						catch (DvdException e1)
						{
							JOptionPane.showMessageDialog(MainFrame.this, "Impossibile caricare il file specificato!", "Errore nel caricamento", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
						}
					}
					statusBar.setText("Pronto");
				}
			});
		}
		return openFileItem;
	}

	/**
	 * This method initializes saveFileItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getSaveFileItem()
	{
		if (saveFileItem == null)
		{
			saveFileItem = new JMenuItem();
			saveFileItem.setText("Salva");
			saveFileItem.setMnemonic(KeyEvent.VK_S);
			saveFileItem.setToolTipText("Salva lo stato corrente");
			saveFileItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Salvataggio su file...");
					try
					{
						if(saveas==false)
						{
							String result=FileChooserUtility.saveFile(MainFrame.this, DaexProperties.getProperty("lastopendir"), "untitled"+DaexProperties.getProperty("extension"), "Salvataggio file", DaexProperties.getProperty("extension"));
							if(result!=null)
							{
								File f=new File(result);
								DaexProperties.addProperty("lastopendir", f.getParent());
								MainManager.getMainManager().save(f.getAbsolutePath());
								saveas=true;
								filename=f.getAbsolutePath();
							}
						}
						else
						{
							MainManager.getMainManager().save(filename);
						}
						permitActions(ActionParams.SAVEONLY, false);
					}
					catch (AlbumWriterException e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Impossibile salvare il file specificato!", "Errore nel salvataggio", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
					}
					statusBar.setText("Pronto");
				}
			});
		}
		return saveFileItem;
	}

	/**
	 * This method initializes saveFileAsItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getSaveFileAsItem()
	{
		if (saveFileAsItem == null)
		{
			saveFileAsItem = new JMenuItem();
			saveFileAsItem.setText("Salva come");
			saveFileAsItem.setMnemonic(KeyEvent.VK_L);
			saveFileAsItem.setToolTipText("Salva lo stato corrente in un nuovo file");
			saveFileAsItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Salvataggio su file...");
					String result=FileChooserUtility.saveFile(MainFrame.this, DaexProperties.getProperty("lastopendir"), "untitled"+DaexProperties.getProperty("extension"), "Salvataggio file", DaexProperties.getProperty("extension"));
					if(result!=null)
					{
						File f=new File(result);
						DaexProperties.addProperty("lastopendir", f.getParent());
						try
						{
							MainManager.getMainManager().save(f.getAbsolutePath());
							saveas=true;
							filename=f.getAbsolutePath();
						}
						catch (AlbumWriterException e1)
						{
							JOptionPane.showMessageDialog(MainFrame.this, "Impossibile salvare il file specificato!", "Errore nel salvataggio", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
						}
					}
					statusBar.setText("Pronto");
				}
			});
		}
		return saveFileAsItem;
	}

	/**
	 * This method initializes encodeItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getEncodeItem()
	{
		if (encodeItem == null)
		{
			encodeItem = new JMenuItem();
			encodeItem.setText("Codifica");
			encodeItem.setMnemonic(KeyEvent.VK_C);
			encodeItem.setToolTipText("Inizia il processo di codifica");
			encodeItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					statusBar.setText("Encoding...");
					getJTabbedPane().setSelectedIndex(1);
					permitActions(ActionParams.OPEN, false);
					permitActions(ActionParams.FULL, false);
					permitActions(ActionParams.ENCODING, true);
					try
					{
						if(!MainManager.getMainManager().startEncode())
						{
							permitActions(ActionParams.OPEN, true);
							permitActions(ActionParams.FULL, true);
							permitActions(ActionParams.ENCODING, false);
						}
					}
					catch (Exception e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Gravi errori di esecuzione, verificare il log!", "Impossibile eseguire la codifica", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
					}
				}
			});
		}
		return encodeItem;
	}

	/**
	 * This method initializes encodeMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getEncodeMenu()
	{
		if (encodeMenu == null)
		{
			encodeMenu = new JMenu();
			encodeMenu.setText("Codifica le tracce come...");
			for(Object e: encodingModels)
			{
				JMenuItem item=new JMenuItem();
				item.setText(e.toString()+" files");
				item.setToolTipText("Codifica tutte le tracce come "+e.toString()+" files");
				item.addActionListener(new java.awt.event.ActionListener()
				{
					public void actionPerformed(java.awt.event.ActionEvent e)
					{
						
					}
				});
				encodeMenu.add(item);
			}
		}
		return encodeMenu;
	}

	/**
	 * This method initializes exitItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getExitItem()
	{
		if (exitItem == null)
		{
			exitItem = new JMenuItem();
			exitItem.setText("Esci");
			exitItem.setMnemonic(KeyEvent.VK_E);
			exitItem.setToolTipText("Esce dal programma");
			exitItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					if(MainManager.getMainManager().checkRun())
					{
						int result=JOptionPane.showConfirmDialog(MainFrame.this, "Kiddin'? Stai codificando... Sei sicuro di voler uscire?", "Domandina...", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon(DaexIcon.INFO));
						if(result!=JOptionPane.YES_OPTION)
						{
							return;
						}
						else
						{
							MainManager.getMainManager().stopEncode();
						}
					}
					dispose();
					System.exit(0);
				}
			});
		}
		return exitItem;
	}

	/**
	 * This method initializes editMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getEditMenu()
	{
		if (editMenu == null)
		{
			editMenu = new JMenu();
			editMenu.setText("Modifica");
			editMenu.setMnemonic(KeyEvent.VK_M);
			editMenu.add(getClearTextItem());
			editMenu.add(getClearTablesItem());
		}
		return editMenu;
	}

	/**
	 * This method initializes clearTextItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getClearTextItem()
	{
		if (clearTextItem == null)
		{
			clearTextItem = new JMenuItem();
			clearTextItem.setText("Riedita le informazioni del disco");
			clearTextItem.setMnemonic(KeyEvent.VK_I);
			clearTextItem.setToolTipText("Reinizializza le informazioni del disco");
			clearTextItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					MainManager.getMainManager().reinit();
				}
			});
		}
		return clearTextItem;
	}

	/**
	 * This method initializes clearTablesItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getClearTablesItem()
	{
		if (clearTablesItem == null)
		{
			clearTablesItem = new JMenuItem();
			clearTablesItem.setText("Pulisci le tabelle di codifica");
			clearTablesItem.setMnemonic(KeyEvent.VK_T);
			clearTablesItem.setToolTipText("Svuota tutte le tabelle degli encoders");
			clearTablesItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					MainManager.getMainManager().clearAll();
				}
			});
		}
		return clearTablesItem;
	}

	/**
	 * This method initializes viewMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getViewMenu()
	{
		if (viewMenu == null)
		{
			viewMenu = new JMenu();
			viewMenu.setText("Visualizza");
			viewMenu.setMnemonic(KeyEvent.VK_V);
			// lasciato per possibili usi futuri
			viewMenu.setEnabled(false);
		}
		return viewMenu;
	}

	/**
	 * This method initializes aboutMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getAboutMenu()
	{
		if (aboutMenu == null)
		{
			aboutMenu = new JMenu();
			aboutMenu.setText("Help");
			aboutMenu.setMnemonic(KeyEvent.VK_H);
			aboutMenu.add(getShowAboutItem());
		}
		return aboutMenu;
	}

	/**
	 * This method initializes showAboutItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getShowAboutItem()
	{
		if (showAboutItem == null)
		{
			showAboutItem = new JMenuItem();
			showAboutItem.setText("About...");
			showAboutItem.setMnemonic(KeyEvent.VK_B);
			showAboutItem.setToolTipText("Visualizza la finestra di about");
			showAboutItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					About.showAbout(MainFrame.this);
				}
			});
		}
		return showAboutItem;
	}

	/**
	 * This method initializes tablesPaneTab	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getTablesPaneTab()
	{
		if (tablesPaneTab == null)
		{
			tablesPaneTab = new JPanel();
			tablesPaneTab.setLayout(new BorderLayout());
			tablesPaneTab.add(getGeneralInfoPane(), BorderLayout.NORTH);
			tablesPaneTab.add(getTablesSplit(), BorderLayout.CENTER);
		}
		return tablesPaneTab;
	}

	/**
	 * This method initializes progressPaneTab	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getProgressPaneTab()
	{
		if (progressPaneTab == null)
		{
			progressPaneTab = new JPanel();
			progressPaneTab.setLayout(new BorderLayout());
			progressPaneTab.add(getProcessTableScroll(), BorderLayout.CENTER);
			progressPaneTab.add(getEncodingOptionsPane(), BorderLayout.SOUTH);
		}
		return progressPaneTab;
	}

	/**
	 * This method initializes generalInfoPane	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getGeneralInfoPane()
	{
		if (generalInfoPane == null)
		{
			GridBagConstraints gridBagConstraints31 = new GridBagConstraints();
			gridBagConstraints31.gridx = 3;
			gridBagConstraints31.fill = GridBagConstraints.BOTH;
			gridBagConstraints31.insets = new Insets(5, 40, 5, 40);
			gridBagConstraints31.weightx = 0.2D;
			gridBagConstraints31.weighty = 0.5D;
			gridBagConstraints31.gridy = 0;
			GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
			gridBagConstraints21.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints21.gridy = 0;
			gridBagConstraints21.weightx = 0.2D;
			gridBagConstraints21.weighty = 0.5D;
			gridBagConstraints21.insets = new Insets(5, 10, 5, 10);
			gridBagConstraints21.gridwidth = 2;
			gridBagConstraints21.gridx = 1;
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.gridx = 0;
			gridBagConstraints12.insets = new Insets(5, 30, 3, 0);
			gridBagConstraints12.weightx = 0.2D;
			gridBagConstraints12.weighty = 0.5D;
			gridBagConstraints12.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints12.gridy = 0;
			jLabel4 = new JLabel();
			jLabel4.setText("DVD device");
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints11.weighty = 0.5D;
			gridBagConstraints11.insets = new Insets(5, 30, 5, 0);
			gridBagConstraints11.gridx = 0;
			gridBagConstraints11.gridy = 3;
			gridBagConstraints11.weightx = 0.2D;
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.gridx = 2;
			gridBagConstraints7.fill = GridBagConstraints.BOTH;
			gridBagConstraints7.weightx = 0.2D;
			gridBagConstraints7.weighty = 0.5D;
			gridBagConstraints7.insets = new Insets(5, 40, 5, 40);
			gridBagConstraints7.gridy = 1;
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints6.gridy = 1;
			gridBagConstraints6.weightx = 0.1D;
			gridBagConstraints6.weighty = 0.5D;
			gridBagConstraints6.insets = new Insets(5, 10, 5, 10);
			gridBagConstraints6.gridx = 1;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.gridx = 0;
			gridBagConstraints5.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints5.weightx = 0.2D;
			gridBagConstraints5.weighty = 0.5D;
			gridBagConstraints5.insets = new Insets(5, 30, 5, 0);
			gridBagConstraints5.gridy = 1;
			jLabel3 = new JLabel();
			jLabel3.setText("Titolo del DVD");
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints4.gridy = 3;
			gridBagConstraints4.weightx = 0.3D;
			gridBagConstraints4.gridwidth = 1;
			gridBagConstraints4.weighty = 0.5D;
			gridBagConstraints4.insets = new Insets(5, 40, 5, 40);
			gridBagConstraints4.gridx = 4;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.gridx = 3;
			gridBagConstraints3.weightx = 0.2D;
			gridBagConstraints3.weighty = 0.5D;
			gridBagConstraints3.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints3.insets = new Insets(5, 30, 5, 0);
			gridBagConstraints3.gridwidth = 1;
			gridBagConstraints3.gridy = 3;
			jLabel2 = new JLabel();
			jLabel2.setText("Genere");
			jLabel2.setHorizontalAlignment(SwingConstants.LEADING);
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints2.gridy = 2;
			gridBagConstraints2.weightx = 0.3D;
			gridBagConstraints2.weighty = 0.5D;
			gridBagConstraints2.insets = new Insets(5, 10, 5, 10);
			gridBagConstraints2.gridwidth = 4;
			gridBagConstraints2.gridx = 1;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints1.weightx = 0.2D;
			gridBagConstraints1.weighty = 0.5D;
			gridBagConstraints1.insets = new Insets(5, 30, 5, 0);
			gridBagConstraints1.gridy = 2;
			jLabel1 = new JLabel();
			jLabel1.setText("Titolo dell'album");
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints.gridy = 3;
			gridBagConstraints.weightx = 0.3D;
			gridBagConstraints.weighty = 0.5D;
			gridBagConstraints.insets = new Insets(5, 10, 5, 10);
			gridBagConstraints.gridwidth = 2;
			gridBagConstraints.gridx = 1;
			jLabel = new JLabel();
			jLabel.setText("Artista");
			jLabel.setHorizontalTextPosition(SwingConstants.TRAILING);
			generalInfoPane = new JPanel();
			generalInfoPane.setLayout(new GridBagLayout());
			generalInfoPane.add(jLabel, gridBagConstraints11);
			generalInfoPane.add(getArtistTextField(), gridBagConstraints);
			generalInfoPane.add(jLabel1, gridBagConstraints1);
			generalInfoPane.add(getAlbumTextField(), gridBagConstraints2);
			generalInfoPane.add(jLabel2, gridBagConstraints3);
			generalInfoPane.add(getGenreComboBox(), gridBagConstraints4);
			generalInfoPane.add(jLabel3, gridBagConstraints5);
			generalInfoPane.add(getDvdSpin(), gridBagConstraints6);
			generalInfoPane.add(getRefreshTitleButton(), gridBagConstraints7);
			generalInfoPane.add(jLabel4, gridBagConstraints12);
			generalInfoPane.add(getDeviceTextField(), gridBagConstraints21);
			generalInfoPane.add(getChangeDeviceButton(), gridBagConstraints31);
		}
		return generalInfoPane;
	}

	/**
	 * This method initializes tablesSplit	
	 * 	
	 * @return javax.swing.JSplitPane	
	 * @todo posizionare correttamente il divisorio
	 */
	private JSplitPane getTablesSplit()
	{
		if (tablesSplit == null)
		{
			tablesSplit = new JSplitPane();
			tablesSplit.setLeftComponent(getLeftTableScroll());
			tablesSplit.setRightComponent(getRightPane());
		}
		return tablesSplit;
	}

	/**
	 * This method initializes artistTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getArtistTextField()
	{
		if (artistTextField == null)
		{
			artistTextField = new JTextField();
			artistTextField.setText(artist);
			artistTextField.setToolTipText("Artista del DVD");
			artistTextField.addFocusListener(focusAdapter);
		}
		return artistTextField;
	}

	/**
	 * This method initializes albumTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getAlbumTextField()
	{
		if (albumTextField == null)
		{
			albumTextField = new JTextField();
			albumTextField.setText(album);
			albumTextField.setToolTipText("Titolo del DVD");
			albumTextField.addFocusListener(focusAdapter);
		}
		return albumTextField;
	}

	/**
	 * This method initializes genreComboBox	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getGenreComboBox()
	{
		if (genreComboBox == null)
		{
			genreComboBox = new JComboBox();
			genreComboBox.setModel(genreModel);
			genreComboBox.setSelectedItem(genreModel.getSelectedItem());
			genreComboBox.setToolTipText("Genere musicale del DVD (se esiste)");
		}
		return genreComboBox;
	}

	/**
	 * This method initializes dvdSpin.
	 * Utilizza un escamotage per evitarne l'editazione diretta
	 * (inserendo il massimo, il minimo ed il valore corrente tutti
	 * uguali al titolo del DVD che si e' scelti di rippare).
	 * 	
	 * @return javax.swing.JSpinner	
	 */
	private JSpinner getDvdSpin()
	{
		if (dvdSpin == null)
		{
			dvdSpin = new JSpinner();
			dvdSpin.setModel(spinModel);
			dvdSpin.setToolTipText("Numero del titolo del DVD");
		}
		return dvdSpin;
	}

	/**
	 * This method initializes changeTitleButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getRefreshTitleButton()
	{
		if (refreshTitleButton == null)
		{
			refreshTitleButton = new JButton();
			refreshTitleButton.setText("Aggiorna");
			refreshTitleButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.CHANGE)));
			refreshTitleButton.setMnemonic(KeyEvent.VK_UNDEFINED);
			refreshTitleButton.setToolTipText("Aggiorna il titolo del DVD usato per il ripping");
			refreshTitleButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					try
					{
						MainManager.getMainManager().changeTitle((Integer) getDvdSpin().getValue());
					}
					catch (DvdException e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Impossibile ricavare i titoli disponibili, verificare l'unita'", "Errore in lettura del dvd", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
						permitActions(ActionParams.FULL, false);
						permitActions(ActionParams.ENCODING, false);
					}
				}
			});
		}
		return refreshTitleButton;
	}

	/**
	 * This method initializes leftTableScroll	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getLeftTableScroll()
	{
		if (leftTableScroll == null)
		{
			leftTableScroll = new JScrollPane();
			leftTableScroll.setViewportView(getDvdTable());
		}
		return leftTableScroll;
	}

	/**
	 * This method initializes dvdTable	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getDvdTable()
	{
		return dvdTable;
	}

	/**
	 * This method initializes processTableScroll	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getProcessTableScroll()
	{
		if (processTableScroll == null)
		{
			processTableScroll = new JScrollPane();
			processTableScroll.setViewportView(getEncodingProgressTable());
		}
		return processTableScroll;
	}

	/**
	 * This method initializes encodingProgressTable	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getEncodingProgressTable()
	{
		if (encodingProgressTable == null)
		{
			encodingProgressTable = new JTable();
			encodingProgressTable.setModel(progressModel);
			encodingProgressTable.setDefaultRenderer(Integer.class, new DaexTableCellRenderer());
		}
		return encodingProgressTable;
	}

	/**
	 * This method initializes encodingOptionsPane	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getEncodingOptionsPane()
	{
		if (encodingOptionsPane == null)
		{
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.fill = GridBagConstraints.BOTH;
			gridBagConstraints10.weightx = 0.05D;
			gridBagConstraints10.weighty = 1.0D;
			gridBagConstraints10.insets = new Insets(5, 0, 5, 10);
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.fill = GridBagConstraints.BOTH;
			gridBagConstraints9.weightx = 0.9D;
			gridBagConstraints9.weighty = 1.0D;
			gridBagConstraints9.insets = new Insets(5, 0, 5, 0);
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.fill = GridBagConstraints.BOTH;
			gridBagConstraints8.weightx = 0.05D;
			gridBagConstraints8.weighty = 1.0D;
			gridBagConstraints8.insets = new Insets(5, 10, 5, 0);
			encodingOptionsPane = new JPanel();
			encodingOptionsPane.setLayout(new GridBagLayout());
			encodingOptionsPane.add(getShowConsoleButton(), gridBagConstraints8);
			encodingOptionsPane.add(getProgressBar(), gridBagConstraints9);
			encodingOptionsPane.add(getAbortButton(), gridBagConstraints10);
		}
		return encodingOptionsPane;
	}

	/**
	 * This method initializes showConsoleButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getShowConsoleButton()
	{
		if (showConsoleButton == null)
		{
			showConsoleButton = new JButton();
			showConsoleButton.setText("Visualizza la console");
			showConsoleButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.CONSOLE)));
			showConsoleButton.setMnemonic(KeyEvent.VK_L);
			showConsoleButton.setToolTipText("Visualizza una nuova finestra con la console dell'output di conversione");
			showConsoleButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					MainManager.getMainManager().showConsole();
				}
			});
		}
		return showConsoleButton;
	}

	/**
	 * This method initializes progressBar	
	 * 	
	 * @return javax.swing.JProgressBar	
	 */
	public JProgressBar getProgressBar()
	{
		if (progressBar == null)
		{
			progressBar = new JProgressBar();
		}
		return progressBar;
	}

	/**
	 * This method initializes abortButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getAbortButton()
	{
		if (abortButton == null)
		{
			abortButton = new JButton();
			abortButton.setText("Ferma l'encoding");
			abortButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.ABORT)));
			abortButton.setMnemonic(KeyEvent.VK_E);
			abortButton.setToolTipText("Blocca l'elaborazione ed elimina i files temporanei");
			abortButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					MainManager.getMainManager().stopEncode();
				}
			});
		}
		return abortButton;
	}

	/**
	 * This method initializes rightPane	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getRightPane()
	{
		if (rightPane == null)
		{
			rightPane = new JPanel();
			rightPane.setLayout(new BoxLayout(getRightPane(), BoxLayout.Y_AXIS));
			rightPane.add(getEncodingPanel1());
			rightPane.add(getEncodingPanel2());
			rightPane.add(getEncodingPanel3());
		}
		return rightPane;
	}

	/**
	 * Returns an encoding panel.
	 * 
	 * @return an encoding panel
	 */
	private JPanel getEncodingPanel1()
	{
		listButtons[0] = new JButton();
		listButtons[0].setBackground(Color.cyan);
		listButtons[0].setIcon(new ImageIcon(getClass().getResource(DaexIcon.ADD)));
		listButtons[0].setToolTipText("Aggiunge la traccia selezionata alla lista");
		listButtons[0].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				if(dvdTable.getSelectedRowCount()!=0)
				{
					for(int i: dvdTable.getSelectedRows())
						encodingModels[0].addElement((Song) dvdTable.getModel().getValueAt(i, DaexTable.OBJECTCOLUMNINDEX));
				}
			}
		});
		listButtons[1] = new JButton();
		listButtons[1].setBackground(Color.cyan);
		listButtons[1].setIcon(new ImageIcon(getClass().getResource(DaexIcon.REMOVE)));
		listButtons[1].setToolTipText("Rimuove la traccia corrente dalla lista");
		listButtons[1].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				int[] el=encodingLists[0].getSelectedIndices();
				if(el.length!=0)
				{
					encodingModels[0].removeElements(encodingLists[0].getSelectedValues());
				}
			}
		});
		listButtons[2] = new JButton();
		listButtons[2].setBackground(Color.cyan);
		listButtons[2].setIcon(new ImageIcon(getClass().getResource(DaexIcon.CLEARLIST)));
		listButtons[2].setToolTipText("Pulisce la lista");
		listButtons[2].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				encodingModels[0].clear();
			}
		});
		encodingLowerPanels[0]=new JPanel();
		encodingLowerPanels[0].setLayout(new FlowLayout());
		encodingLowerPanels[0].add(listButtons[0]);
		encodingLowerPanels[0].add(listButtons[1]);
		encodingLowerPanels[0].add(listButtons[2]);
		encodingLists[0]=new JList();
		encodingLists[0].setModel(encodingModels[0]);
		encodingLists[0].setTransferHandler(new DaexSongTransferHandler());
		encodingLists[0].setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		encodingLists[0].setCellRenderer(this);
		encodingLists[0].setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		encodingPanels[0]=new JPanel();
		encodingPanels[0].setLayout(new BorderLayout());
		encodingPanels[0].setBorder(BorderFactory.createTitledBorder(null, encodingModels[0].toString(), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
		encodingPanels[0].add(encodingLowerPanels[0], BorderLayout.SOUTH);
		encodingPanels[0].add(encodingLists[0], BorderLayout.CENTER);
		return encodingPanels[0];
	}

	/**
	 * Returns an encoding panel.
	 * 
	 * @return an encoding panel
	 */
	private JPanel getEncodingPanel2()
	{
		listButtons[3] = new JButton();
		listButtons[3].setBackground(Color.orange);
		listButtons[3].setIcon(new ImageIcon(getClass().getResource(DaexIcon.ADD)));
		listButtons[3].setToolTipText("Aggiunge la traccia selezionata alla lista");
		listButtons[3].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				if(dvdTable.getSelectedRowCount()!=0)
				{
					for(int i: dvdTable.getSelectedRows())
						encodingModels[1].addElement((Song) dvdTable.getModel().getValueAt(i, DaexTable.OBJECTCOLUMNINDEX));
				}
			}
		});
		listButtons[4] = new JButton();
		listButtons[4].setBackground(Color.orange);
		listButtons[4].setIcon(new ImageIcon(getClass().getResource(DaexIcon.REMOVE)));
		listButtons[4].setToolTipText("Rimuove la traccia corrente dalla lista");
		listButtons[4].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				int[] el=encodingLists[1].getSelectedIndices();
				if(el.length!=0)
				{
					encodingModels[1].removeElements(encodingLists[1].getSelectedValues());
				}
			}
		});
		listButtons[5] = new JButton();
		listButtons[5].setBackground(Color.orange);
		listButtons[5].setIcon(new ImageIcon(getClass().getResource(DaexIcon.CLEARLIST)));
		listButtons[5].setToolTipText("Pulisce la lista");
		listButtons[5].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				encodingModels[1].clear();
			}
		});
		encodingLowerPanels[1]=new JPanel();
		encodingLowerPanels[1].setLayout(new FlowLayout());
		encodingLowerPanels[1].add(listButtons[3]);
		encodingLowerPanels[1].add(listButtons[4]);
		encodingLowerPanels[1].add(listButtons[5]);
		encodingLists[1]=new JList();
		encodingLists[1].setModel(encodingModels[1]);
		encodingLists[1].setTransferHandler(new DaexSongTransferHandler());
		encodingLists[1].setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		encodingLists[1].setCellRenderer(this);
		encodingLists[1].setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		encodingPanels[1]=new JPanel();
		encodingPanels[1].setLayout(new BorderLayout());
		encodingPanels[1].setBorder(BorderFactory.createTitledBorder(null, encodingModels[1].toString(), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
		encodingPanels[1].add(encodingLowerPanels[1], BorderLayout.SOUTH);
		encodingPanels[1].add(encodingLists[1], BorderLayout.CENTER);
		return encodingPanels[1];
	}

	/**
	 * Returns an encoding panel.
	 * 
	 * @return an encoding panel
	 */
	private JPanel getEncodingPanel3()
	{
		listButtons[6] = new JButton();
		listButtons[6].setBackground(Color.yellow);
		listButtons[6].setIcon(new ImageIcon(getClass().getResource(DaexIcon.ADD)));
		listButtons[6].setToolTipText("Aggiunge la traccia selezionata alla lista");
		listButtons[6].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				if(dvdTable.getSelectedRowCount()!=0)
				{
					for(int i: dvdTable.getSelectedRows())
						encodingModels[2].addElement((Song) dvdTable.getModel().getValueAt(i, DaexTable.OBJECTCOLUMNINDEX));
				}
			}
		});
		listButtons[7] = new JButton();
		listButtons[7].setBackground(Color.yellow);
		listButtons[7].setIcon(new ImageIcon(getClass().getResource(DaexIcon.REMOVE)));
		listButtons[7].setToolTipText("Rimuove la traccia corrente dalla lista");
		listButtons[7].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				int[] el=encodingLists[2].getSelectedIndices();
				if(el.length!=0)
				{
					encodingModels[2].removeElements(encodingLists[2].getSelectedValues());
				}
			}
		});
		listButtons[8] = new JButton();
		listButtons[8].setBackground(Color.yellow);
		listButtons[8].setIcon(new ImageIcon(getClass().getResource(DaexIcon.CLEARLIST)));
		listButtons[8].setToolTipText("Pulisce la lista");
		listButtons[8].addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				encodingModels[2].clear();
			}
		});
		encodingLowerPanels[2]=new JPanel();
		encodingLowerPanels[2].setLayout(new FlowLayout());
		encodingLowerPanels[2].add(listButtons[6]);
		encodingLowerPanels[2].add(listButtons[7]);
		encodingLowerPanels[2].add(listButtons[8]);
		encodingLists[2]=new JList();
		encodingLists[2].setModel(encodingModels[2]);
		encodingLists[2].setTransferHandler(new DaexSongTransferHandler());
		encodingLists[2].setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		encodingLists[2].setCellRenderer(this);
		encodingLists[2].setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		encodingPanels[2]=new JPanel();
		encodingPanels[2].setLayout(new BorderLayout());
		encodingPanels[2].setBorder(BorderFactory.createTitledBorder(null, encodingModels[2].toString(), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
		encodingPanels[2].add(encodingLowerPanels[2], BorderLayout.SOUTH);
		encodingPanels[2].add(encodingLists[2], BorderLayout.CENTER);
		return encodingPanels[2];
	}

	/**
	 * This method initializes printTracksTableButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getPrintTracksTableButton()
	{
		if (printTracksTableButton == null)
		{
			printTracksTableButton = new JButton();
			printTracksTableButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.PRINT)));
			printTracksTableButton.setMnemonic(KeyEvent.VK_P);
			printTracksTableButton.setToolTipText("Stampa la tabella delle tracce");
			printTracksTableButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					try
					{
						MainManager.getMainManager().printTracks();
					}
					catch (PrinterException e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Impossibile stampare la tabella", "Errore di stampa", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
					}
				}
			});
		}
		return printTracksTableButton;
	}

	/**
	 * This method initializes printTracksTableItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getPrintTracksTableItem()
	{
		if (printTracksTableItem == null)
		{
			printTracksTableItem = new JMenuItem();
			printTracksTableItem.setMnemonic(KeyEvent.VK_P);
			printTracksTableItem.setToolTipText("Stampa la tabella delle tracce");
			printTracksTableItem.setText("Stampa");
			printTracksTableItem.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					try
					{
						MainManager.getMainManager().printTracks();
					}
					catch (PrinterException e1)
					{
						JOptionPane.showMessageDialog(MainFrame.this, "Impossibile stampare la tabella", "Errore di stampa", JOptionPane.ERROR_MESSAGE, new ImageIcon(DaexIcon.ERROR));
					}
				}
			});
		}
		return printTracksTableItem;
	}
	
	/**
	 * Costruttore; setta gli attributi di classe con i
	 * valori specificati.
	 * 
	 * @param encodingModels i modelli per i pannelli con le liste degli encoders
	 * @param dvdTable istanza di JTable per la gestione delle tracce
	 * @param progressModel il modello per la tabella di progresso
	 * @param genreModel il modello della combo box dei generi
	 * @param artist l'artista dell'album
	 * @param album il titolo dell'album
	 * @param spinModel il modello per lo spinner
	 */
	public MainFrame(SortedListModel[] encodingModels, JTable dvdTable, TableModel progressModel, ComboBoxModel genreModel, String artist, String album, SpinnerModel spinModel)
	{
		super();
		if(encodingModels.length!=3)
		{
			throw new IllegalArgumentException("Can't find exactly 3 list models!");
		}
		this.encodingModels=encodingModels;
		this.dvdTable=dvdTable;
		this.progressModel=progressModel;
		this.genreModel=genreModel;
		this.artist=artist;
		this.album=album;
		this.spinModel=spinModel;
		initialize();
	}

	/**
	 * Costruttore; setta gli attributi di classe con i
	 * valori specificati, indicando anche il device utilizzato
	 * (come stringa).
	 * 
	 * @param encodingModels i modelli per i pannelli con le liste degli encoders
	 * @param dvdTable istanza di JTable per la gestione delle tracce
	 * @param progressModel il modello per la tabella di progresso
	 * @param genreModel il modello della combo box dei generi
	 * @param artist l'artista dell'album
	 * @param album il titolo dell'album
	 * @param spinModel il modello dello spinner
	 * @param device il device (come stringa)
	 */
	public MainFrame(SortedListModel[] encodingModels, JTable dvdTable, TableModel progressModel, ComboBoxModel genreModel, String artist, String album, SpinnerModel spinModel, String device)
	{
		super();
		if(encodingModels.length!=3)
		{
			throw new IllegalArgumentException("Can't find exactly 3 list models!");
		}
		this.encodingModels=encodingModels;
		this.dvdTable=dvdTable;
		this.progressModel=progressModel;
		this.genreModel=genreModel;
		this.artist=artist;
		this.album=album;
		this.spinModel=spinModel;
		this.device=device;
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize()
	{
		this.setSize(855, 650);
		this.setJMenuBar(getJJMenuBar());
		this.setContentPane(getJContentPane());
		this.setTitle("Dvd Audio EXtractor");
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new WindowAdapter()
		{

			/**
			 * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
			 */
			@Override
			public void windowClosing(WindowEvent e)
			{
				if(MainManager.getMainManager().checkRun())
				{
					int result=JOptionPane.showConfirmDialog(MainFrame.this, "Kiddin'? Stai codificando... Sei sicuro di voler uscire?", "Domandina...", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon(DaexIcon.INFO));
					if(result!=JOptionPane.YES_OPTION)
					{
						return;
					}
					else
					{
						MainManager.getMainManager().stopEncode();
					}
				}
				dispose();
				System.exit(0);
			}
			
		});
		if(((DaexTable) dvdTable).getAlbum()==null)
		{
			permitActions(ActionParams.OPEN, true);
			permitActions(ActionParams.FULL, false);
			permitActions(ActionParams.ENCODING, false);
		}
		else
		{
			permitActions(ActionParams.FULL, true);
		}
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane()
	{
		if (jContentPane == null)
		{
			statusBar = new JLabel();
			statusBar.setText("Pronto");
			statusBar.setFont(new Font("Dialog", Font.ITALIC, 12));
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJJToolBar(), BorderLayout.NORTH);
			jContentPane.add(statusBar, BorderLayout.SOUTH);
			jContentPane.add(getJTabbedPane(), BorderLayout.CENTER);
		}
		return jContentPane;
	}
	
	/**
	 * @see java.awt.Component#setVisible(boolean)
	 */
	@Override
	public void setVisible(boolean b)
	{
		super.setVisible(b);
		if(b)
		{
			getTablesSplit().setDividerLocation(0.7);
		}
	}

	/**
	 * This method initializes jTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getDeviceTextField()
	{
		if (deviceTextField == null)
		{
			deviceTextField = new JTextField();
			deviceTextField.setEditable(false);
			if(device!=null)
			{
				deviceTextField.setText(device);
			}
			else // non usato il device
			{
				getChangeDeviceButton().setEnabled(false);
				getDeviceTextField().setText("Non usato");
			}
		}
		return deviceTextField;
	}

	/**
	 * This method initializes changeDeviceButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getChangeDeviceButton()
	{
		if (changeDeviceButton == null)
		{
			changeDeviceButton = new JButton();
			changeDeviceButton.setText("Cambia");
			changeDeviceButton.setIcon(new ImageIcon(getClass().getResource(DaexIcon.CHANGE)));
			changeDeviceButton.setToolTipText("Cambia il device in uso");
			changeDeviceButton.addActionListener(new java.awt.event.ActionListener()
			{
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					String result=null;
					try
					{
						ArrayList<String> elements=DvdNative.getDiscDevices();
						result=(String) JOptionPane.showInputDialog(MainFrame.this, "Scegli il nuovo device di lettura:", "Scelta device lettore DVD", JOptionPane.QUESTION_MESSAGE, new ImageIcon(DaexIcon.INFO), elements.toArray(), elements.get(elements.indexOf(deviceTextField.getText())));
						if(result!=null && !result.equals(deviceTextField.getText()))
						{
							MainManager.getMainManager().setAlbum(result);
							permitActions(ActionParams.FULL, true);
							permitActions(ActionParams.ENCODING, false);
						}
					}
					catch (DvdException e1)
					{
						permitActions(ActionParams.FULL, false);
						permitActions(ActionParams.ENCODING, false);
					}
					finally
					{
						if(result!=null)
						{
							deviceTextField.setText(result);
						}
					}
				}
			});
		}
		return changeDeviceButton;
	}
	
	/**
	 * Metodo per ottenere l'artista dell'album.
	 * 
	 * @return l'artista dell'album
	 */
	public String getArtist()
	{
		return getArtistTextField().getText();
	}
	
	/**
	 * Metodo per ottenere il titolo dell'album.
	 * 
	 * @return il titolo dell'album
	 */
	public String getAlbum()
	{
		return getAlbumTextField().getText();
	}
	
	/**
	 * Metodo per ottenere il device utilizzato.
	 * 
	 * @return il device utilizzato come stringa
	 */
	public String getDevice()
	{
		return getDeviceTextField().getText();
	}
	
	/**
	 * Metodo per ottenere l'indice della traccia utilizzata.
	 * 
	 * @return l'indice del titolo utilizzato sul dvd
	 */
	public int getDvdTitle()
	{
		return (Integer) dvdSpin.getValue();
	}
	
	/**
	 * Metodo per aggiungere le informazioni per l'album a fronte ad
	 * esempio di un caricamento di file.
	 * 
	 * @param album il titolo dell'album da settare
	 * @param artist l'artista dell'album da settare
	 * @param title il numero del titolo in uso
	 */
	public void addAlbumInfo(String album, String artist, int title)
	{
		getAlbumTextField().setText(album);
		getArtistTextField().setText(artist);
		genreComboBox.setSelectedItem(genreModel.getSelectedItem());
		dvdSpin.setModel(new SpinnerNumberModel(title, title, title, 0));
		dvdSpin.setValue(title);
	}
	
	/**
	 * Metodo per l'aggancio di un listener al text input per
	 * l'artista del dvd: una classe che si registri qui puo'
	 * quindi ad esempio propagare la modifica agli oggetti
	 * della tabella,
	 * 
	 * @param l il listener da agganciare
	 */
	public void addArtistActionListener(ActionListener l)
	{
		getArtistTextField().addActionListener(l);
	}
	
	/**
	 * Metodo per l'aggancio di un listener alla combo che
	 * gestisce il genere musicale dell'album, cosi' da
	 * poter propagare l'informazione alla base di dati.
	 * 
	 * @param l il listener da agganciare
	 */
	public void addGenreActionListener(ActionListener l)
	{
		getGenreComboBox().addActionListener(l);
	}

	/**
	 * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean)
	 */
	public Component getListCellRendererComponent(JList arg0, Object arg1, int arg2, boolean arg3, boolean arg4)
	{
		Component c=null;
		if(arg1 instanceof Song)
		{
			c=renderer.getListCellRendererComponent(arg0, ((Song) arg1).getTitle(), arg2, arg3, arg4);
			if(!arg3)
			{
				if(((SortedListModel) arg0.getModel()).indexOf(arg1)%2==0)
				{
					c.setBackground(Color.white);
				}
				else
				{
					c.setBackground(new Color(230, 250, 250));
				}
			}
		}
		else
		{
			DaexLogger.getDaexLogger().severe("Il cell renderer di una lista di encoding ha ricevuto un oggetto diverso da Song: "+arg1.getClass());
			renderer.getListCellRendererComponent(arg0, arg1, arg2, arg3, arg4);
		}
		return c;
	}

	/**
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent evt)
	{
		if(MainManager.MODIFYANY.equals(evt.getPropertyName()))
		{
			permitActions(ActionParams.SAVEONLY, true);
		}
		else if(EncoderExecutor.EXECPROPERTY.equals(evt.getPropertyName()) && evt.getNewValue().equals(new Boolean(false)))
		{
			permitActions(ActionParams.OPEN, true);
			permitActions(ActionParams.ENCODE, true);
			permitActions(ActionParams.FULL, true);
			permitActions(ActionParams.ABORT, false);
			// la console rimane aperta per poter eventualmente continuare
			// a guardarne l'output
		}
	}
	
}  //  @jve:decl-index=0:visual-constraint="10,10"
